package ntd.util.frame.task.handle.fm.util;

import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import com.c.opt.ComOpt;
import com.c.opt.query.ComOptQueryWrapper;
import com.modular.extra.fm.FactoryFmOpt;
import com.modular.extra.fm.data.OptFmData;
import com.modular.extra.fm.data.push.opt.OptFmDataPush;
import com.modular.extra.fm.device.opt.OptFmDevice;
import com.modular.extra.fm.online.opt.OptOnline;
import com.modular.extra.fm.site.FmSiteOpt;
import com.tool.ToolRedisson;
import ntd.util.UtilCatch;
import ntd.util.frame.task.handle.fm.bo.FmDataRecordBo;
import ntd.util.frame.task.handle.fm.bo.FmDataRecordItemBo;
import org.redisson.api.RBucket;

import java.time.Duration;
import java.util.List;

public class ToolFmData {

    public static final OptFmDevice OPT_FM_DEVICE = FactoryFmOpt.OPT_FM_DEVICE;
    public static final OptFmDataPush OPT_FM_DATA_PUSH = FactoryFmOpt.OPT_FM_DATA_PUSH;
    public static final OptFmData OPT_FM_DATA = FactoryFmOpt.OPT_FM_DATA;
    public static final OptOnline OPT_FM_ON_LINE = FactoryFmOpt.OPT_FM_ON_LINE;
    public static final FmSiteOpt FM_SITE_OPT = FactoryFmOpt.FM_SITE_OPT;

    // 基站设备操作
    public static ComOpt<FmDataRecordBo> dataRecordOpt = FactoryFmOpt.dataRecordOpt;
    public static ComOpt<Object> siteInfoOpt = FactoryFmOpt.siteInfoOpt;
    public static ComOpt<Object> omUserOpt = FactoryFmOpt.omUserOpt;
    public static ComOpt<FmDataRecordItemBo> dataRecordItemOpt = FactoryFmOpt.dataRecordItemOpt;

    public static List<Entity> newset(String mn) {
        return UtilCatch.tryCatch(() -> {
            Db db = dataRecordOpt.db();
            String sql = StrUtil.format("SELECT dr.mn,\n" +
                    "       dr.has_o,\n" +
                    "       dr.data_state,\n" +
                    "       dr.cn,\n" +
                    "       dr.create_time,\n" +
                    "       dr.has_a,\n" +
                    "       dr.id,\n" +
                    "       dr.has_e,\n" +
                    "       dr.rule_id\n" +
                    "FROM data_record dr\n" +
                    "         INNER JOIN\n" +
                    "     (select MAX(dr.create_time) as create_time, dr.mn as mn\n" +
                    "      FROM data_record dr\n" +
                    "               INNER JOIN site_info si ON (dr.mn = si.mn and dr.cn = 61)\n" +
                    "      GROUP BY dr.mn) t\n" +
                    "     on (dr.create_time = t.create_time and dr.mn = t.mn {})", StrUtil.isBlank(mn) ? "" : StrUtil.format("and t.mn = '{}'", mn));
            List<Entity> siteDatas = db.query(sql);

            for (Entity siteData : siteDatas) {
                List<Entity> factors = db.query("SELECT * \n" +
                        "FROM data_record_item WHERE data_id = " + siteData.getStr("id"));
                siteData.set("items", factors);
            }

            return siteDatas;
        });
    }

    
    public static FmDataRecordItemBo initDataItem(FmDataRecordItemBo fmDataRecordItemBo, String mn) {
        ToolRedisson.me.lock_run("initDataItem" + fmDataRecordItemBo.getDataId() + fmDataRecordItemBo.getFactorCode(), () -> {
            ComOptQueryWrapper eq = dataRecordItemOpt.query()
                    .eq("data_id", fmDataRecordItemBo.getDataId())
                    .eq("factor_code", fmDataRecordItemBo.getFactorCode());
            FmDataRecordItemBo bean = dataRecordItemOpt.getBean(eq);

            // 封装id
            Opt.ofNullable(bean).ifPresent(item -> fmDataRecordItemBo.setId(item.getId()));
            // 封装设备id
            Opt.ofEmptyAble(OPT_FM_DEVICE.listDevice(mn)).ifPresent(fmDeviceDos -> {
                fmDataRecordItemBo.setDeviceId(fmDeviceDos.get(0).getId());
            });
            // 处理_数据
            if ("_".equals(fmDataRecordItemBo.getWeightValue())) {
                fmDataRecordItemBo.setWeightValue(null);
            }
            if ("_".equals(fmDataRecordItemBo.getConvertValue())) {
                fmDataRecordItemBo.setConvertValue(null);
            }
            if ("_".equals(fmDataRecordItemBo.getTotalValue())) {
                fmDataRecordItemBo.setTotalValue(null);
            }
            if ("_".equals(fmDataRecordItemBo.getFactorValue())) {
                fmDataRecordItemBo.setFactorValue(null);
            }

//        fmDataRecordItemBo.setDeviceId(Opt.ofEmptyAble(OPT_FM_DEVICE.listDevice(mn)).orElseThrow(() ->
//            new ComException("基站[{}]找不到设备信息", mn)).get(0).getId());
            // 新增判定 - 如果没有因子值不进行存储
            if (StrUtil.isNotBlank(fmDataRecordItemBo.getFactorValue())) {
                // 保存后id封装
                fmDataRecordItemBo.setId(dataRecordItemOpt.syncBean(fmDataRecordItemBo));
            }
        });
        return fmDataRecordItemBo;
    }

    public static Entity findSiteInfo(String mn) {
        RBucket<Entity> bucket = ToolRedisson.me.redisson.getBucket("fm-site-info-" + mn);
        if (!bucket.isExists()) {
            bucket.set(siteInfoOpt.query().eq("mn", mn).get(), Duration.ofSeconds(60 * 10));
        }
        return bucket.get();
    }

    public static Entity findOmUser(String omUserId) {
        RBucket<Entity> bucket = ToolRedisson.me.redisson.getBucket("fm-om-user-" + omUserId);
        if (!bucket.isExists()) {
            bucket.set(omUserOpt.getById(omUserId), Duration.ofSeconds(60 * 10));
        }
        return bucket.get();
    }

    public static void main(String[] args) {
        StaticLog.info(JSONUtil.toJsonStr(findOmUser("48")));
        StaticLog.info(JSONUtil.toJsonStr(findSiteInfo("41060301G00024")));
    }
}
